//不同的运动轨迹挂载同一类子图
let x1;
let y1;
let graph1;
let x2;
let y2;
let r2;
let graph2;
let x3;
let y3;
let graph3;
let graph4;
let graph5;
function setup() {
    createCanvas(windowWidth, windowHeight);
    background(40, 40, 40);
    frameRate(30);
    //在这里把所有画图的方法都加入进去，注意传入的是函数体 pic0 ,不是 pic0()
    x1=0;
    y1=0;
    graph1=new EllipseEx(100,125,250);
    x2=0;
    y2=0;
    r2=0;
    graph2=new EllipseEx(100,220,23);
    x3=0;
    y3=0;
    graph3= new ParabolaEx();

    graph4=new HeartCurve();

    graph5 = new ClockCurve();


}

function draw() {
    // background(40, 188, 213);

    //确定第一条函数作为运动轨迹 正弦
    if (x1 > 1000 || x1 < 50) x1=50;
    x1++;
    y1=40*sin(0.033*x1)+100;
    //挂载一个对象到该轨迹点x1 y1;
    graph1.run(x1,y1);


    //确定第二条函数作为运动轨迹　椭圆
    if (r2 > 1000 || r2 < 50) r2=50;
    r2++;
    x2=4+4*cos(r2);
    y2=12+6*sin(r2);
    //挂载一个对象到该轨迹点x2 y2;
    graph2.run(x2+200,y2+200);

    if (x3 > 500 || x3 < 50) x3=50;
    x3++;
    y3=x3;
    debugTrack(x3,y3)
    graph3.run(x3,y3)

    graph4.run(800,400)
    graph5.run(100,200)
}
function mouseClicked() {
    if (graph1.r>150) graph1.r=100;
    else graph1.r=200;

    graph3.rect.r= (graph3.rect.r>200)?100:255;
}
// 超级椭圆
class  EllipseEx {
    constructor(r,g,b){
        this.p =0;
        this.r=r;
        this.g=g;
        this.b=b;
    }
    run(x,y){
        push();
        translate(x, y);

        this.p += ( Math.PI / 30);
        rotate(this.p);

        fill(this.r,this.g,this.b);
        ellipse(0, 0, 20, 40);

        pop();
    }

}

//超级抛物线?直线
class ParabolaEx {
    constructor(){
        this.x4 =0;
        this.y4= 0;
        this.rect = new RectEx(255, 193, 193);
    }
    run(x,y){

        fill(255, 0, 0);
        ellipse(x, y, 60, 60);
        line(x - 25, y + 30, x - 15, y + 60);
        line(x + 25, y + 30, x + 15, y + 60);
        fill(255, 193, 193);
        rect(x - 30, y + 60, 60, 30);

        if (this.x4 > 500 || this.x4 < 50) this.x4=50;
        this.x4++;
        this.y4=this.x4-4;
        this.rect.run(this.x4,this.y4);

    }
}
class RectEx{
    constructor(r,g,b){
        this.p=0;
        this.r=r;
        this.g=g;
        this.b=b;
    }
    run(x,y){
        push();
        translate(x, y);

        this.p += ( PI / 30);
        rotate(this.p);

        fill(this.r,this.g,this.b);
        rect(20, 20, 10, 10);

        pop();
    }

}
//这里决定把参数也封装进来
class HeartCurve {
    constructor(){
        this.r =0;
        this.x=0;
        this.y=0;
    }

    run(xs,ys){
        //直接开坐标系，此处设计为一个常量坐标
        push();
        translate(xs, ys);
        fill(255, 10, 0);
        ellipse(0, 0, 20, 20);
        if (this.r > 500 || this.r < 50) this.r=50;
        this.r++;
        //
        //参数方程：x=a*(2*cos(t)-cos(2*t)),y=a*(2*sin(t)-sin(2*t))
        //
        this.x=80*(2*cos(this.r)-cos(2*this.r));
        this.y=60*(2*sin(this.r)-sin(2*this.r));
        debugTrack(this.x,this.y)


        pop();


    }
}
class ClockCurve {
    constructor(){
        this.r =0;
        this.x=0;
        this.y=0;
    }

    run(xs,ys){
        //直接开坐标系，此处设计为一个常量坐标
        push();
        translate(xs, ys);
        fill(150, 100, 10);
        ellipse(0, 0, 20, 20);
        if (this.r > 100 || this.r < 50) this.r=50;
        this.r++;
        //
        //参数方程摆线
        //
        this.x=10*(this.r-sin(this.r));
        this.y=10*(1-cos(this.r));
        debugTrack(this.x,this.y)

        pop();


    }
}
function debugTrack(x, y) {
    fill(255, 10, 0);
    ellipse(x, y, 10, 10);
}